#include<reg51.h>
#define uchar unsigned char

//变量定义
uchar key, sel=0x01, num;
uchar code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,
											 0x6d,0x7d,0x07,0x7f,0x6f};
bit second, mode=1, add, dec;
uchar clock[3]={0,0,0};		//分别表示时、分、秒
uchar buffer[3]={0,0,0};	//分别存放时、分、秒缓冲数据

//函数声明
void dlms(uchar x); //延时函数
uchar keys(); //按键函数
void display(); //显示函数
void adjust(); //调整函数

main()
{
	//定时器中断初始化
	TMOD=0x01;
	EA=1;
	ET0=1;
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256; //50000个脉冲信号==50ms
	TR0=1; //启动定时器
	while(1)
	{
		key=keys(); //获取按键值
		switch(key)
		{
			//当按下第1个按键：改变工作模式
			case 0xfe: mode=~mode; break;
			//当按下第2个按键：分针+1
			case 0xfd: add=1; dec=0; break;
			//当按下第3个按键：分针-1
			case 0xfb: add=0; dec=1; break;
			default: break;
		}
		//display();
		if(mode==1) TR0=1; //表示没有按键，没有改变模式
		if(mode==0) //表示按下第1个按键，改变为调整模式
		{
			TR0=0; //关闭定时器
			if(add==1)
			{
				adjust();
			}
			if(dec==1)
			{
				adjust();
			}
		}
		display();
 }
}

//获取按键值的函数
uchar keys()
{
	P2=0xff;
	if((P2&0xff)!=0xff) //表示有键按下
	{
		dlms(20); //延时去抖动
		if((P2&0xff)!=0xff) //再次判断
			return (P2&0xff);
	} else
		return(0);
	for(;;) //等待按键释放
	{
		if((P2&0xff)==0xff) //表示没有按下
			break;
	}
}

//延时函数
void dlms(uchar x)
{
	uchar a, b;
	for(a=x;a>0;a--)
		for(b=200;b>0;b--);
}

//显示函数
void display()
{
	uchar i;
	buffer[0]=clock[0];
	buffer[1]=clock[1];
	buffer[2]=clock[2];
	for(i=0;i<3;i++)
	{
		P1=dispcode[buffer[i]%10]; //个位数
		P0=sel;
		sel=sel<<1;
		P1=0x00; //数码管去重影
		P1=dispcode[buffer[i]/10]; //十位数
		P0=sel;
		sel=sel<<1;
		P1=0x00;
		if(sel==0x40) //0x40: 0100 0000
			sel=0x01;	//0x01: 0000 0001
	}
}

//调整时间的函数
void adjust()
{
	if(add==1) //表示 +
	{
		clock[1]=clock[1]+1; //分针加1
		if(clock[1]==60) //当分针加到60时
		{
			clock[1]=0; //分针清零
			clock[2]=clock[2]+1; //时针加1
		}
		if(clock[2]==24) //当时针加到24时
			clock[2]=0; //时针清零
	}
	if(dec==1) //表示 -
	{
		clock[1]=clock[1]-1; //分针减1
		if(clock[1]==0) //当分针减到0时
		{
			clock[1]=59; //分针置为59
			clock[2]=clock[2]-1; //时针减1
		}
		if((clock[2]==0)&&(clock[1]==0)) //当时针和分针同时为0时
		{
			clock[2]=23; //时针置为23
			clock[1]=59; //分针置为59
		}
	}
	while((P2&0xff)!=0xff); //等待按键释放
	add=0; dec=0; //清除加1和减1操作
}

//定时器中断函数
void timer0(void) interrupt 1 using 1
{
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	num++;
	if(num==20) //50ms*20=1s
	{
		second=1;
		num=0;
	}
	if(second)
	{
		second=0;
		clock[0]=clock[0]+1; //秒针加1
		if(clock[0]==60) //当秒针加到60时
		{
			clock[0]=0; //秒针清零
			clock[1]=clock[1]+1; //分针加1
			if(clock[1]==60) //当分针加到60时
			{
				clock[1]=0; //分针清零
				clock[2]=clock[2]+1; //时针加1
			}
			if(clock[2]==24) //当时针加到24时
				clock[2]=0; //时针清零
		}
	}
}